home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C++
/
Applications
/
PICSee Dust 1.01
/
Quaternary Source
/
Marquee.c
< prev
next >
Wrap
Text File
|
1995-11-16
|
6KB
|
229 lines
/*
** James "im" Beninghaus
*/
/*
Version history
2.0 Nov 5 95 HTD
"Updated" code for today's generation ;-).
Added a callback parameter (so you could display the mouse coordinates
while dragging the marquee, for example).
Also added a "crop area" - you can confine the marquee selection
to this area.
2.1 Nov 6
Added TrackMarqueeOpaque() and ConstrainPointWithinRect().
The problem with TrackMarquee occurs with color images that have
grayish colors. Because of the use of patXor, the resulting
marquee is grayish as well. The marquee is then VERY hard to see.
The problem is, if you invert gray, you pretty much get gray!
So TrackMarqueeOpaque adds an update callback procedure.
TrackMarqueeOpaque does not use any patXor tricks but instead
just plainly draws the marquee rect. However, we need a way to
update the marquee (to erase the old marquee rect) which is
what the callback proc is for.
*/
#include "Marquee.h"
// ---------------------------------------------------------------------------
#define TICKDELAY 2
/*
** Description
** TrackMarquee will display a marquee similar to the
** selection rectangle tool in MacPaint™. It is assumed that the
** current port has been set before calling.
**
** Parameters
** start : the local coordinates where the mouse down occured. Mandatory.
** trackMouseProc : a callback procedure that will give you the current mouse's
** location. Optional (pass NULL)
** cropToRect : a rect in which to confine the marquee. Optional (pass NULL)
** resultRect : the final rectangle that was selected. Mandatory
*/
void TrackMarquee(
Point start,
const Rect *cropToRect,
Rect *resultRect) {
/*
** there are fifteen patterns defined here
** each one eight bytes long starting at :
** patterns[0], patterns[1], patterns[2], patterns[3],
** patterns[4], patterns[5], patterns[6], patterns[7]
*/
static unsigned char patterns[] = {
0xF8, 0xF1, 0xE3, 0xC7, 0x8F,
0x1F, 0x3E, 0x7C, 0xF8, 0xF1,
0xE3, 0xC7, 0x8F, 0x1F, 0x3E
};
Point mouse; /* the current mouse location */
short index; /* the index of the current patterns array */
Rect nowRect, /* the current rectangle to be framed */
thenRect; /* the last rectangle to be framed */
long nowTicks, /* the current tick count */
thenTicks; /* the last tick count */
PenState penState; /* the saved pen state on entry to procedure */
thenTicks = 0;
index = 0;
GetPenState(&penState);
PenMode(patXor);
PenPat((ConstPatternParam)&patterns[index]);
SetRect(&nowRect, start.h, start.v, start.h, start.v);
FrameRect(&nowRect);
thenRect = nowRect;
while (StillDown()) {
nowTicks = TickCount();
GetMouse(&mouse);
if (cropToRect != NULL) {
ConstrainPointWithinRect(&mouse, cropToRect);
}
SetMobiusRect(&nowRect, start.h, start.v, mouse.h, mouse.v);
if (((thenTicks + TICKDELAY) < nowTicks ? thenTicks = nowTicks, true : false) ||
(!EqualRect(&nowRect, &thenRect))) {
FrameRect(&thenRect);
index = index < 7 ? index + 1 : 0;
PenPat((ConstPatternParam)&patterns[index]);
FrameRect(&nowRect);
thenRect = nowRect;
}
}
FrameRect(&thenRect);
SetPenState(&penState);
*resultRect = thenRect;
} // END TrackMarquee
// ---------------------------------------------------------------------------
void TrackMarqueeOpaque(
Point start,
TrackUpdateProc trackUpdateProc,
const RGBColor *marqueeColor,
const Rect *cropToRect,
Rect *resultRect) {
Point mouse; /* the current mouse location */
Rect nowRect, /* the current rectangle to be framed */
thenRect; /* the last rectangle to be framed */
long nowTicks, /* the current tick count */
thenTicks; /* the last tick count */
thenTicks = 0;
SetRect(&nowRect, start.h, start.v, start.h, start.v);
thenRect = nowRect;
while (StillDown()) {
nowTicks = TickCount();
GetMouse(&mouse);
if (cropToRect != NULL) {
ConstrainPointWithinRect(&mouse, cropToRect);
}
SetMobiusRect(&nowRect, start.h, start.v, mouse.h, mouse.v);
if (nowTicks > (thenTicks + TICKDELAY)) {
thenTicks = nowTicks;
// Erase old marquee
trackUpdateProc(&thenRect, &nowRect);
FrameMarquee(&nowRect, marqueeColor);
thenRect = nowRect;
}
else if (!EqualRect(&nowRect, &thenRect) && nowTicks > (thenTicks + TICKDELAY)) {
thenTicks = nowTicks;
trackUpdateProc(&thenRect, &nowRect);
FrameMarquee(&nowRect, marqueeColor);
thenRect = nowRect;
}
}
// Erase any visages of the marquee
trackUpdateProc(&thenRect, &nowRect);
*resultRect = thenRect;
} // END TrackMarqueeOpaque
// ---------------------------------------------------------------------------
static long sIndex = 0; /* the index of the current patterns array */
void FrameMarquee(const Rect *marqueeRect, const RGBColor *marqueeColor) {
static unsigned char patterns[] = {
0xF8, 0xF1, 0xE3, 0xC7, 0x8F,
0x1F, 0x3E, 0x7C, 0xF8, 0xF1,
0xE3, 0xC7, 0x8F, 0x1F, 0x3E
};
PenState penState;
RGBColor saveFore, saveBack, backColor;
GetPenState(&penState);
GetForeColor(&saveFore);
GetBackColor(&saveBack);
backColor.red = backColor.green = backColor.blue = 0xFFFF; // White
RGBBackColor(&backColor);
sIndex = sIndex < 7 ? sIndex + 1 : 0;
PenPat((ConstPatternParam)&patterns[sIndex]);
if (marqueeColor != NULL)
RGBForeColor(marqueeColor);
FrameRect(marqueeRect);
RGBForeColor(&saveFore);
RGBBackColor(&saveBack);
SetPenState(&penState);
} // END FrameMarquee
// ---------------------------------------------------------------------------
void SetMobiusRect(
Rect *rect,
short anchorLeft,
short anchorTop,
short curRight,
short curBottom) {
if (anchorLeft > curRight) {
rect->left = curRight;
rect->right = anchorLeft;
} else {
rect->left = anchorLeft;
rect->right = curRight;
}
if (anchorTop > curBottom) {
rect->top = curBottom;
rect->bottom = anchorTop;
} else {
rect->top = anchorTop;
rect->bottom = curBottom;
}
} // END SetMobiusRect
// ---------------------------------------------------------------------------
void ConstrainPointWithinRect(Point *point, const Rect *constrainRect) {
if (point->h < constrainRect->left)
point->h = constrainRect->left;
else if (point->h > constrainRect->right)
point->h = constrainRect->right;
if (point->v < constrainRect->top)
point->v = constrainRect->top;
else if (point->v > constrainRect->bottom)
point->v = constrainRect->bottom;
} // END ConstrainPointWithinRect